#pragma once
#include "imessageport.h"
#include "CriticalSection.h"
#include "SingleLock.h"


namespace cupid
{

#define LOCKOBJ		SingleLock xLock(&m_xCtrl, true)
#define UNLOCKOBJ	xLock.Unlock()

struct	MessagePacket
{
	unsigned int		m_from;
	unsigned int		m_packet;
	unsigned int		m_varType;
	char				m_bufData[MAX_MSGPACKSIZE];
};

class MessagePort :
	public IMessagePort
{
protected:
	MessagePort			(int port) { LOCKOBJ; m_id = port; m_state = STATE_CLOSED; m_haveMsg = NULL; }
	virtual ~MessagePort	() { clear(); }

	IMessagePort*	getInterface() { LOCKOBJ; return (IMessagePort*)this; }

protected: // Interface
	virtual bool	isOpen	() { LOCKOBJ; return m_state == STATE_OK; }

	virtual int		getID	() { LOCKOBJ; return m_id; }

	virtual int		getSize	() { return m_setPort.size(); }

	virtual bool	open	();

	virtual bool	close	();

	virtual bool	send	(int port, int packet, VAR_TYPE varType, const void* buf);

	virtual bool	recv	(int port, int packet, VAR_TYPE varType, void* buf, MessageStatus* status);

	virtual bool	waitMsg	(int sec);


protected:
	bool		pushMsg		(int port, int packet, VAR_TYPE varType, const void* buf);

	bool		popMsg		(int *port, int *packet, VAR_TYPE *varType, void* buf);

	static int	size_of_type (int type);

	bool		init();
	void		clear();

protected:
	int			m_id;
	enum { STATE_OK, STATE_CLOSED };
	int			m_state;
	typedef	vector<MessagePacket*>	MSG_SET;
	MSG_SET		m_setMsg;						
	HANDLE		m_haveMsg;		
	int			m_debugPackets;
	MSG_SET		m_setRecycle;
	CriticalSection 	m_xCtrl;	

public:
	static bool	initPortSet(int port);
	static void	clearPortSet();
	static IMessagePort*	getInterface(int port) ;
	static int	getQueueSize(int port)	;
protected: //static
	typedef	vector<MessagePort*> PORT_SET;
	static PORT_SET		m_setPort;

};

}